import path from 'path-browserify'
import useUserStore from '@/store/modules/user'
import useRouterStore from '@/store/modules/route'
import dayjs from 'dayjs'
import { replace } from 'lodash-es'

// 深拷贝
export function deepClone(target) {
  // 定义一个变量
  let result
  // 如果当前需要深拷贝的是一个对象的话
  if (typeof target === 'object') {
    // 如果是一个数组的话
    if (Array.isArray(target)) {
      result = [] // 将result赋值为一个数组，并且执行遍历
      for (let i in target) {
        // 递归克隆数组中的每一项
        result.push(deepClone(target[i]))
      }
      // 判断如果当前的值是null的话；直接赋值为null
    } else if (target === null) {
      result = null
      // 判断如果当前的值是一个RegExp对象的话，直接赋值
    } else if (target.constructor === RegExp) {
      result = target
    } else {
      // 否则是普通对象，直接for in循环，递归赋值对象的所有值
      result = {}
      for (let i in target) {
        result[i] = deepClone(target[i])
      }
    }
    // 如果不是对象的话，就是基本数据类型，那么直接赋值
  } else {
    result = target
  }
  // 返回最终结果
  return result
}

// 防抖
export const debounce = (fn, delay = 300, immediate = true) => {
  let timer = null // 借助闭包
  return function() {
    if (timer) {
      clearTimeout(timer)
    }
    if (immediate) {
      let callNow = !timer
      timer = setTimeout(() => {
        timer = null
      }, delay)
      if (callNow) {
        fn.apply(this, arguments)
      }
    } else {
      timer = setTimeout(() => {
        fn.apply(this, arguments)
      }, delay)
    }
  }
}

// 节流
export function throttle(fn, delay = 300) {
  let valid = true
  return function() {
    if (!valid) {
      return false
    }
    // 工作时间，执行函数并且在间隔期内把状态位设为无效
    valid = false
    setTimeout(() => {
      fn.apply(this, arguments)
      valid = true
    }, delay)
  }
}

function hasPermission(permission) {
  const userStore = useUserStore()
  return userStore.btnPermissions.some(v => v === permission)
}

export function auth(value) {
  let auth
  if (typeof value === 'string') {
    auth = hasPermission(value)
  } else {
    auth = value.some(item => {
      return hasPermission(item)
    })
  }
  return auth
}

export function authAll(value) {
  const auth = value.every(item => {
    return hasPermission(item)
  })
  return auth
}

export function isExternalLink(path) {
  return /^(https?:|mailto:|tel:)/.test(path)
}

export function resolveRoutePath(basePath, routePath) {
  if (isExternalLink(routePath)) {
    return routePath
  }
  if (isExternalLink(basePath)) {
    return basePath
  }
  return basePath ? path.resolve(basePath, routePath) : routePath
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url) {
  url = !url ? window.location.href : url
  const search = url.substring(url.indexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

export function obj2Param(obj) {
  return Object.keys(obj).map(key => {
    return key + '=' + obj[key]
  }).join('&')
}

/**
 * 删除当前url中指定参数
 * @param names 数组或字符串
 * @returns {string}
 */
export function funcUrlDel(names) {
  if (typeof (names) === 'string') {
    names = [names]
  }
  const local = window.location
  const obj = {}
  const arr = local.search.substr(1).split('&')
  let url = ''
  // 获取参数转换为object
  for (let i = 0; i < arr.length; i++) {
    arr[i] = arr[i].split('=')
    obj[arr[i][0]] = arr[i][1]
  }
  // 删除指定参数
  for (let i = 0; i < names.length; i++) {
    delete obj[names[i]]
  }
  url = local.origin + local.pathname
  for (const i in obj) {
    if (i) {
      url += '?' + JSON.stringify(obj).replace(/["{}]/g, '').replace(/:/g, '=').replace(/,/g, '&')
      break
    }
  }
  return url
}

// 下载文件流
export function downloadFile(data, fileName) {
  // 对于<a>标签，只有 Firefox 和 Chrome（内核） 支持 download 属性，IE10+支持blob但是依然不支持download
  if ('download' in document.createElement('a')) { // 支持a标签download的浏览器
    const url = window.URL.createObjectURL(new Blob([data]))// 为文件流创建构建下载链接
    const link = document.createElement('a')// 创建a标签
    link.style.display = 'none'
    link.href = url
    link.setAttribute('download', fileName)// 设置a标签的下载动作和下载文件名
    document.body.appendChild(link)
    link.click()// 执行下载
    document.body.removeChild(link)// 释放标签
  } else { // 其他浏览器
    navigator.msSaveBlob(data, fileName)
  }
}

// 通过传入的url下载
export function downloadFileByUrl(url) {
  const a = document.createElement('a')
  a.href = import.meta.env.VITE_APP_API_BASEURL + url
  a.style.display = 'none'
  document.body.appendChild(a)
  a.click()// 执行下载
  document.body.removeChild(a)// 释放标签
}

// 获取文件后缀
export function getFileSuffix(file) {
  return file.substring(file.lastIndexOf('.') + 1)
}

// 格式化视频时长
export function parseVideoTime(time) {
  let hh = parseInt(time / 3600)
  if (hh < 10) hh = '0' + hh
  let mm = parseInt((time - hh * 3600) / 60)
  if (mm < 10) mm = '0' + mm
  let ss = parseInt((time - hh * 3600) % 60)
  if (ss < 10) ss = '0' + ss
  let length = hh + ':' + mm + ':' + ss
  if (time > 0) {
    return length
  } else {
    return '-'
  }
}

// 根据key分类
export function groupByKey(arr, key) {
  const map = {}
  const dest = []
  for (let i = 0; i < arr.length; i++) {
    const ai = arr[i]
    if (!map[ai[key]]) {
      dest.push({
        show: true,
        type: ai[key],
        data: [ai]
      })
      map[ai[key]] = ai
    } else {
      for (let j = 0; j < dest.length; j++) {
        const dj = dest[j]
        if (dj.type === ai[key]) {
          dest[j].data.push(ai)
        }
      }
    }
  }
  return dest
}

// 文件大小转换
export function getFileSize(size) {
  if (!size) {
    return ''
  }

  const num = 1024.00 // byte

  if (size < num) { return size + 'B' }
  if (size < Math.pow(num, 2)) { return (size / num).toFixed(2) + 'K' } // kb
  if (size < Math.pow(num, 3)) { return (size / Math.pow(num, 2)).toFixed(2) + 'M' } // M
  if (size < Math.pow(num, 4)) { return (size / Math.pow(num, 3)).toFixed(2) + 'G' } // G
  return (size / Math.pow(num, 4)).toFixed(2) + 'T' // T
}

// 数字行号转中文
export function numberToChina(num) {
  const arr = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一']
  return arr[num]
}

// 调整顺序，arr 数组，indexAdd 添加元素的位置，indexDel 删除元素的位置（indexAdd与indexDel交换位置）
export function handleChangeOrder(arr, indexAdd, indexDel) {
  arr[indexAdd] = arr.splice(indexDel, 1, arr[indexAdd])[0]
  return arr
}
// 上移，与前一个元素交换顺序
export function handleUp(list, index) {
  if (index - 1 >= 0) {
    return handleChangeOrder(list, index, index - 1)
  } else {
    ElMessage.error('已经到顶了')
  }
}
// 下移，与后一个元素交换顺序
export function handleDown(list, index) {
  if (index + 1 < list.length) {
    return handleChangeOrder(list, index, index + 1)
  } else {
    ElMessage.error('已经到底了')
  }
}

// 打开tlias客户端
export function openTlias(data) {
  const temp = JSON.stringify(data)
  openUriWithInputTimeoutHack('tlias:///' + window.btoa(temp), () => {
    ElMessage.error('未安装客户端，请前往下载')
  }, () => {
    console.log('检测到，已经安装了客户端')
  })
}

// 检测是否安装了客户端
/**
 * uri 打开客户端的uri
 * failCb 打开客户端失败回调
 * successCb 打开客户端成功回调
 */
function openUriWithInputTimeoutHack(uri, failCb, successCb) {
  let target = document.createElement('input')
  target.style.width = '0'
  target.style.height = '0'
  target.style.position = 'fixed'
  target.style.top = '0'
  target.style.left = '0'
  document.body.appendChild(target)

  target.focus()
  var handler = _registerEvent(target, 'blur', onBlur)
  console.log('focus')
  function onBlur() {
    console.log('blur')
    successCb && successCb()
    handler.remove()
    clearTimeout(timeout)
    document.body.removeChild(target)
  }

  // will trigger onblur
  location.href = uri

  // Note: timeout could vary as per the browser version, have a higher value
  var timeout = setTimeout(function() {
    console.log('setTimeout')
    failCb && failCb()
    handler.remove()
    document.body.removeChild(target)
  }, 1000)
}

function _registerEvent(target, eventType, cb) {
  if (target.addEventListener) {
    target.addEventListener(eventType, cb)
    return {
      remove: function() {
        target.removeEventListener(eventType, cb)
      }
    }
  } else {
    target.attachEvent(eventType, cb)
    return {
      remove: function() {
        target.detachEvent(eventType, cb)
      }
    }
  }
}

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text(val) {
  const div = document.createElement('div')
  div.innerHTML = val
  return div.textContent || div.innerText
}

// 获取两个日期之间的所有日期
export function getDates(startDate, endDate) {
  const dates = []
  let curDate = dayjs(startDate)
  while (curDate.isBefore(dayjs(endDate))) {
    dates.push(curDate.format('YYYY-MM-DD'))
    curDate = curDate.add(1, 'day')
  }
  dates.push(dayjs(endDate).format('YYYY-MM-DD'))
  return dates
}

// 设置面包屑
export function setBreadcrumb(breadcrumb) {
  const routerStore = useRouterStore()
  routerStore.setBreadCrumb(breadcrumb)
}

// 字符串全部替换成指定字符
export const replaceAll = (str, findText, repText) => {
  return replace(str, findText, repText)
}
